import { Segment } from "./segment.js";
import { SourceMap } from "./sourcemap.js";
import { matrixToString } from "../utils/short.js";

const debugMatrixToString = (matrix) => {
  return matrixToString(matrix, ["|", ";"]);
};

/**
 * @debug add some helpers for debug info.
 */
export class SourceMapDebug extends SourceMap {
  _mappings_raw = [];
  constructor(options) {
    super(options);
  }
  /**
   * @debug
   */
  toJSON() {
    return {
      mappings: this.mappings,
      mappings_array_string: this.debug_mappingsString,
      mappings_offset_string: this.debug_mappingsOffsetString,
      mappings_array: this.debug_mappingsArray,
      mappings_offset: this.debug_mappingsOffsetArray,
      mappings_raw: this.debug_mappingsRaw,
    };
  }

  /**
   * @debug
   * @returns {Segment[][]}
   */
  get debug_mappingsRaw() {
    return this._mappings_raw;
  }

  /**
   * @debug
   * @returns {number[][]}
   */
  get debug_mappingsArray() {
    console.log("debug_mappingsArray");
    return this._mappings_raw.map((line) => line.map((seg) => seg.toArray()));
  }

  /**
   * @debug
   * @returns {string}
   */
  get debug_mappingsString() {
    return debugMatrixToString(this.debug_mappingsArray);
  }

  /**
   * @debug
   * @returns {number[][]}
   */
  get debug_mappingsOffsetArray() {
    const result = [];
    let prev = new Segment(0, 0, 0, 0, 0);
    let prevName = 0;
    for (const line of this._mappings_raw) {
      const lineResult = [];
      for (const segment of line) {
        const offset = segment.offset(prev);

        // special for `.name`
        if (segment.name >= 0) {
          offset.name = segment.name - prevName;
          prevName = segment.name;
        }

        const unencoded = offset.toArray();
        lineResult.push(unencoded);

        prev = segment;
      }
      result.push(lineResult);
    }

    return result;
  }

  /**
   * @debug
   * @returns {string}
   */
  get debug_mappingsOffsetString() {
    return debugMatrixToString(this.debug_mappingsOffsetArray);
  }
}
